package com.bskj.common.bean.model;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.util.DateParseException;
import org.apache.commons.httpclient.util.DateUtil;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.bskj.common.utils.StringUtils;

public abstract class BaseJSONModel extends BaseModels implements BaseModel {
	private static final Collection<String> dateFormats = Arrays.asList("yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd",
			"yyyy-MM-dd");
	
	public BaseModel parse(String string) {
		try {
			JSONObject jsonObj = JSONObject.parseObject(string);
			Class<?> modelClass = this.getClass();

			//找出所有的方法
			Method[] methods = modelClass.getMethods();
			Map<String, Method> methodMap = new HashMap<>();
			for (Method method : methods) {
				methodMap.put(method.getName(), method);
			}

			//找到私有成员，以及set方法
			Field[] fields = modelClass.getDeclaredFields();
			if (fields != null && fields.length > 0) {
				for (Field field : fields) {
					String fieldName = field.getName();
					String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
					Method setMethod = methodMap.get(setMethodName);
					if (setMethod != null) {
						Class<?>[] types = setMethod.getParameterTypes();
						//model的set方法 参数只有一个
						if (types != null && types.length > 0) {
							Class<?> prameterType = types[0];
							Object param = jsonObj.get(fieldName);
							if (param != null) {
								if (prameterType.isAssignableFrom(Integer.class)) {
									setMethod.invoke(this, Integer.valueOf(param.toString()));
								} else if (prameterType.isAssignableFrom(String.class)) {
									setMethod.invoke(this, param.toString());
								} else if (prameterType.isAssignableFrom(Date.class)) {
									setMethod.invoke(this, DateUtil.parseDate(param.toString(), dateFormats));
								}
							}
						}
					}
				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (DateParseException e) {
			e.printStackTrace();
		}
		return this;
	}

	public String toJSONString() {
		JSONObject jsonObj = new JSONObject();
		try {
			Class<?> modelClass = this.getClass();
			//找出所有的方法
			Method[] methods = modelClass.getMethods();
			Map<String, Method> methodMap = new HashMap<>();
			for (Method method : methods) {
				methodMap.put(method.getName(), method);
			}

			//找出所有的私有成员和get方法
			//找到私有成员，以及set方法
			Field[] fields = modelClass.getDeclaredFields();
			if (fields != null && fields.length > 0) {
				for (Field field : fields) {
					String fieldName = field.getName();
					String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
					Method getMethod = methodMap.get(getMethodName);
					if (getMethod != null) {
						Class<?> returnType = getMethod.getReturnType();
						Object returnObj = getMethod.invoke(this);
						if (returnObj != null) {
							if (returnType.isAssignableFrom(Date.class)) {
								jsonObj.put(fieldName, DateUtil.formatDate((Date) returnObj, "yyyy-MM-dd HH:mm:ss"));
							} else {
								jsonObj.put(fieldName, returnObj.toString());
							}
						} else {
							jsonObj.put(fieldName, null);
						}
					}
				}
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return JSONObject.toJSONString(jsonObj,SerializerFeature.WriteMapNullValue,SerializerFeature.PrettyFormat);
	}
	
	
}
